﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using DataObject.Database;
using System.Drawing;
using System.Text.RegularExpressions;
using DataObject.Helpers;

public partial class AccReceivableReport : System.Web.UI.Page
{
    const string url = @"/Pages/Reports/AccReceivableReport.aspx?AgentID={0}&BoatID={1}&ClientType={2}&FromDate={3:d}&ToDate={4:d}&SortField={5}&SortOption={6}";

    #region Fields & Properties
    private GridViewHelper helper;
    private DateTime? _fromDate, _toDate;
    private string _agentID, _boatID, _guestId, Xls;
    private int _clientType;

    private int PageIndex
    {
        get
        {
            if (Request["page"] != null)
            {
                return int.Parse(Request["page"].ToString());
            }
            return 1;
        }
    }
    #endregion

    #region Events

    /// <summary>
    /// Page Load
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            this.grv.RowDataBound += new GridViewRowEventHandler(grv_RowDataBound);

            this.LoadBoats();

            // Process Searching
            this.GetQueryString();

            if (Xls == String.Empty)
            {
                this.Search();
            }
            else
            {
                this.ExportCustomer();
            }
        }
    }

    /// <summary>
    /// RowDataBound
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void grv_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            GridViewRow gvRow = e.Row;
            var hdfColor = gvRow.FindControl("hdfColor") as HiddenField;
            var hdfCss_Monday = gvRow.FindControl("hdfCss_Monday") as HiddenField;
            var hdfCss_Tuesday = gvRow.FindControl("hdfCss_Tuesday") as HiddenField;
            var hdfCss_Wednesday = gvRow.FindControl("hdfCss_Wednesday") as HiddenField;
            var hdfCss_Thursday = gvRow.FindControl("hdfCss_Thursday") as HiddenField;
            var hdfCss_Friday = gvRow.FindControl("hdfCss_Friday") as HiddenField;
            var hdfCss_Saturday = gvRow.FindControl("hdfCss_Saturday") as HiddenField;
            var hdfCss_Sunday = gvRow.FindControl("hdfCss_Sunday") as HiddenField;

            decimal d;
            if (decimal.TryParse(gvRow.Cells[11].Text, out d))
            {
                if (d > 0)
                {
                    gvRow.Cells[11].ForeColor = Color.Red;
                    gvRow.Cells[11].Font.Bold = true;
                }
            }
        }
        // gvRow.CssClass = "calendarBooked";
    }

    /// <summary>
    /// Button Find
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnSearch_Click(object sender, EventArgs e)
    {
        GetOnForm();
        Response.Redirect(string.Format(url, _agentID, _boatID, _clientType, _fromDate, _toDate));
    }

    /// <summary>
    /// Button Print
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnReport_Click(object sender, EventArgs e)
    {
        this.GetQueryString();
        this.Print();
    }

    #endregion

    #region Methods

    /// <summary>
    /// Load Boats
    /// </summary>
    private void LoadBoats()
    {
        // Load Boats
        var boatList = DataObject.DataAccess.BoatDAO.CreateInstant().GetAllBoats();
        boatList.Insert(0, new BoatEntity() { BoatName = "All boats", BoatID = String.Empty });

        this.ddlBoat.DataSource = boatList;
        this.ddlBoat.DataTextField = "BoatName";
        this.ddlBoat.DataValueField = "BoatID";
        this.ddlBoat.DataBind();
    }

    /// <summary>
    /// 
    /// </summary>
    private void GetQueryString()
    {
        // ClientType
        _clientType = -1;
        if (Request["ClientType"] != null) int.TryParse(Request["ClientType"], out _clientType);

        _guestId = (Request["GuestID"] ?? String.Empty);
        _agentID = (Request["AgentID"] ?? String.Empty);
        _boatID = (Request["BoatID"] ?? String.Empty);
        Xls = (Request["XLS"] ?? String.Empty);

        DateTime fromDate, toDate;

        // FromDate
        if (DateTime.TryParse(Request["FromDate"], System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out fromDate))
            _fromDate = fromDate.Date;
        else
            _fromDate = DateTime.Today;

        // ToDate
        if (DateTime.TryParse(Request["ToDate"], System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out toDate))
            _toDate = toDate.Date;
        else
            _toDate = DateTime.Today;

        this.txtAgentID.Text = _agentID;
        this.txtFromDate.Text = _fromDate.Value.ToShortDate();
        this.txtToDate.Text = _toDate.Value.ToShortDate();
        this.ddlBoat.SelectedValue = _boatID;
        this.ddlClientType.SelectedValue = _clientType.ToString();
    }

    /// <summary>
    /// 
    /// </summary>
    private void GetOnForm()
    {
        DateTime fromDate, toDate;
        // FromDate
        if (DateTime.TryParse(txtFromDate.Text, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out fromDate))
            _fromDate = fromDate.Date;
        else
            _fromDate = DateTime.Now;

        // ToDate
        if (DateTime.TryParse(txtToDate.Text, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out toDate))
            _toDate = toDate.Date;
        else
            _toDate = DateTime.Now;

        // Client Type
        _clientType = Int32.Parse(this.ddlClientType.SelectedValue);
        _boatID = this.ddlBoat.SelectedValue;
        _agentID = this.txtAgentID.Text;
    }

    /// <summary>
    /// Search method
    /// </summary>
    private void Search()
    {
        int count = 0;
        BuildOnGrid(out count, PageIndex, define.PageSize);

        smartPager.PageSize = define.PageSize;
        smartPager.QueryStringKey = "page";
        smartPager.RowCount = count;
        smartPager.UrlFormatString = string.Format(url, _agentID, _boatID, _clientType, _fromDate, _toDate) + "&page={0}";
        smartPager.Visible = count > define.PageSize;
    }

    private void BuildOnGrid(out int count)
    {
        BuildOnGrid(out count, null, null);
    }

    private void BuildOnGrid(out int count, int? pageIndex, int? pageSize)
    {
        HashSet<string> hs = new HashSet<string>();
        hs.Add("DepartureDate ASC");
        hs.Add("ReservationCode ASC");

        IList<ViewAccountReceivableHeader> collection = DataObject.DataAccess.ReservationDAO.CreateInstant().GetViewAccountReceivableHeader(_fromDate, _toDate, _clientType, _boatID, _agentID, pageIndex, pageSize, out count, hs);

        helper = new GridViewHelper(this.grv);
        helper.RegisterSummary("SubTotal", SummaryOperation.Sum);
        helper.RegisterSummary("Deposit", SummaryOperation.Sum);
        helper.RegisterSummary("Paid", SummaryOperation.Sum);
        helper.RegisterSummary("Balance", SummaryOperation.Sum);

        grv.DataSource = collection;
        grv.DataBind();

        grdCustomer.DataSource = DataObject.DataAccess.ReservationDAO.CreateInstant().GetCustomer(_fromDate, _toDate, _clientType, _boatID, _agentID);
        grdCustomer.DataBind();
    }

    /// <summary>
    /// Print method
    /// </summary>
    private void Print()
    {
        int count = 0;
        BuildOnGrid(out count);

        var form = new System.Web.UI.HtmlControls.HtmlForm();
        form.Controls.Add(grv); // gvParent là gridview 

        string attachment = String.Format("attachment; filename=receivable{0:yyyyMMdd}.xls", DateTime.Now);
        Response.ClearContent();
        Response.AddHeader("content-disposition", attachment);
        Response.ContentType = "application/ms-excel";
        Response.Charset = String.Empty;
        Response.ContentEncoding = System.Text.Encoding.Unicode;
        Response.BinaryWrite(System.Text.Encoding.Unicode.GetPreamble());

        System.IO.StringWriter stw = new System.IO.StringWriter();
        HtmlTextWriter htextw = new HtmlTextWriter(stw);
        this.Controls.Add(form);
        form.RenderControl(htextw);

        Response.Write(stw.ToString());
        Response.End();
    }

    private void ExportCustomer()
    {
        int count = 0;
        HashSet<string> hs = new HashSet<string>();
        hs.Add("DepartureDate ASC");
        hs.Add("ReservationCode ASC");

        IList<ViewAccountReceivableHeader> reservations = DataObject.DataAccess.ReservationDAO.CreateInstant().GetViewAccountReceivableHeader(_fromDate, _toDate, _clientType, _boatID, _guestId, null, null, out count, hs);
        if (null != reservations && reservations.Count > 0)
        {
            string filename = "pages/Reports/template/sendcustomer.htm";
            string filePath = HttpContext.Current.Server.MapPath(HttpContext.Current.Request.ApplicationPath.Replace("/", "\\")) + "\\" + filename;
            string body = Helper.ReadTemplateFile(filePath);

            DateTime date = _fromDate ?? _toDate ?? DateTime.Today;
            this.SplitDetail(body, _guestId, date.Month, date.Year, reservations);
        }
    }

    /// <summary>
    /// Split method
    /// </summary>
    private void SplitDetail(string body, string customerId, int month, int year, IEnumerable<ViewAccountReceivableHeader> reservations)
    {
        body = body.Replace("[Month]", month.ToString());
        body = body.Replace("[Year]", year.ToString());
        body = body.Replace("[CustomerName]", customerId);
        body = body.Replace("[SubTotal]", reservations.Sum(x => x.SubTotal).ToString("#,##0.##"));

        var form = new System.Web.UI.HtmlControls.HtmlForm();
        form.InnerHtml = FillDetails(body, "loop1", reservations,
            "BoatID", "DepartureDate", "RouteName", "ReservationCode", "UnitPrice", "ExtraFee", "ShuttlePrice", "GuestID", "NumOfPax", "ExSubTotal", "CruiseRate", "SubTotal");

        string attachment = String.Format("attachment; filename=BookingsOf{0}.xls", customerId.ToFilename());
        Response.ClearContent();
        Response.AddHeader("content-disposition", attachment);
        Response.ContentType = "application/ms-excel";
        Response.Charset = String.Empty;
        Response.ContentEncoding = System.Text.Encoding.Unicode;
        Response.BinaryWrite(System.Text.Encoding.Unicode.GetPreamble());

        System.IO.StringWriter stw = new System.IO.StringWriter();
        HtmlTextWriter htextw = new HtmlTextWriter(stw);
        this.Controls.Add(form);
        form.RenderControl(htextw);

        Response.Write(stw.ToString());
        Response.End();
    }

    private string FillDetails(string template, string loopID, IEnumerable<ViewAccountReceivableHeader> collection, params string[] columns)
    {
        string content = String.Empty;

        template = Regex.Replace(template, "\r\n", String.Empty);

        Regex reg = new Regex(String.Concat("<!--", loopID, "-->(.*?)<!--/", loopID, "-->"));
        if (reg.IsMatch(template))
        {
            var htmlRow = reg.Match(template).Groups[1].Value;
            var rowTemplate = htmlRow;

            int length = collection.Count();
            for (int i = 0; i < length; i++)
            {
                htmlRow = htmlRow.Replace("[#Seq]", (i + 1).ToString());
                foreach (var c in columns)
                {
                    var item = collection.ElementAt(i);
                    var value = item.GetType().GetProperty(c).GetValue(item, null);
                    if (null == value)
                    {
                        htmlRow = htmlRow.Replace("[#" + c + "]", String.Empty);
                    }
                    else
                    {
                        if (value is decimal)
                        {
                            decimal d = Convert.ToDecimal(value);
                            htmlRow = htmlRow.Replace("[#" + c + "]", d.ToString("#,##0.##"));
                        }
                        else if (value is int)
                        {
                            int integer = Convert.ToInt32(value);
                            htmlRow = htmlRow.Replace("[#" + c + "]", integer.ToString("#,##0.##"));
                        }
                        else
                        {
                            htmlRow = htmlRow.Replace("[#" + c + "]", value.ToString());
                        }

                    }
                }

                if (i == length - 1)
                    continue;

                htmlRow += rowTemplate;
            }

            content = reg.Replace(template, htmlRow);
        }

        return content;
    }

    #endregion

}